#pragma once

#include <mutex>
#include <string>
#include <functional>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
#include "sdkconfig.h"

using work_time_t = uint8_t;
using work_count_t = uint8_t;
using work_para_t = struct {
    work_time_t     worktime;   // 工作时间（分钟）
    work_time_t     pausetime;  // 暂停时间（分钟）
    work_count_t    workcount;  // 工作次数（次数）
};
using work_done_func_t = std::function<void(void*)>;

enum class SwitchState {
    IDLE,
    RUN,
    PAUSE,
    FINISHED
};

class MySwitch {
public:
    MySwitch(gpio_num_t pin, bool level=true);
    ~MySwitch();

    void set_work_para(work_time_t work, work_time_t pause=0, work_count_t count=1);
    work_time_t get_work_time() const { return m_work_para.worktime; }
    work_time_t get_pause_time() const { return m_work_para.pausetime; }
    work_count_t get_work_count() const { return m_work_para.workcount; }
    SwitchState get_current_state() const { return m_state; }
    void set_work_done_callback(work_done_func_t callback, void* arg);
    void start();
    void stop();
private:
    void turn_on();
    void turn_off();
    void toggle_state();

    std::mutex      m_mutex;
    bool            m_active_level; // 激活电平(true表示高电平)
    gpio_num_t      m_ctrl_pin;     // 控制引脚
    work_para_t     m_work_para;    // 工作参数
    SwitchState     m_state;        // 开头所处状态
    work_time_t     m_time_left;    // 阶段（状态）剩余时间
    work_count_t    m_count_left;   // 剩余次数
    uint16_t        m_start_second;
    uint16_t        m_work_second;  // 工作时系统秒数（计算不足1分钟时间）
    std::string     m_work_info;
    TimerHandle_t   m_timer_handle; // 计时器句柄

    work_done_func_t    m_on_work_done;
    void*               m_on_work_done_arg;
};
